/*
 * jquery.contextMenu-4.0.js
 *
 * Depends:
 *      jquery-1.8.0.js
 *      jquery.contextMenu.osce.button.css
 *      jquery.contextMenu.osce.css
 * Example:
 *
 * Copyright (c) 1989-2013 Trend Micro Incorporated, All Rights Reserved
*/
(function($) {
    var PLUGIN_NAME = "contextMenu";
    $.fn[PLUGIN_NAME] = function(methodOrOptions) {
        if (typeof methodOrOptions == "string") {
            var publicMethods = $.fn[PLUGIN_NAME].publicMethods[methodOrOptions];
            if (publicMethods) {
                var args = Array.prototype.slice.call(arguments, 1);
                return this.each(function() {
                    publicMethods(this, args);
                });
            } else {
                return this[PLUGIN_NAME](methodOrOptions, args);
            }
        }
        methodOrOptions = methodOrOptions || {};
        return this.each(function() {
            var Internal = $.data(this, PLUGIN_NAME);

            if (Internal) {
                $.extend(true , {} , Internal.options, methodOrOptions);
            } else {
                var o = {
                    options: $.extend(true, {}, $.fn[PLUGIN_NAME].defaults, methodOrOptions)
                };
                var p = $.extend(true , {} , $.fn[PLUGIN_NAME].base , o);
                $.data(this, PLUGIN_NAME, p );
            }
            $.fn[PLUGIN_NAME].internalMethods.init(this);
        });
    };
    $.fn[PLUGIN_NAME].internalMethods = {
        /**
         *  Initialises the plugin.
         *
        **/
        init : function(elem){
            var that = this;
                base = that.getData(elem),
                base.$elem = $(elem);
            /**********************************************/
            if(base.options.buttonMode === true){
                this.displayContextmenuByDefault(elem);
            }else{
                base.$appendTo = $(base.options.appendTo);

                $(base.options.exclude).each(function(){

                    $(this).bind('contextmenu' , function(e){
                        base.$appendTo.find('div.'+base.themePrefix+base.options.theme).remove();
                        e.preventDefault(e);
                        return false;
                    }).bind('mousedown',function(e){
                        $(base.options.appendTo).find('div.'+base.themePrefix+base.options.theme).remove();
                        e.preventDefault(e);
                        return false;
                    }).bind('mouseup',function(e){
                        $(base.options.appendTo).find('div.'+base.themePrefix+base.options.theme).remove();
                        e.preventDefault(e);
                        return false;
                    });
                });
               // $(base.options.exclude)

                base.$elem.bind('contextmenu',{elem:elem,that:this},this.showContextmenu);
            }
        },
        /**
         *  Returns the data for relevant for this plugin
         *
        **/
        getData : function(elem){
            return $.data(elem, PLUGIN_NAME);
        },
        /**
         *
         *
        **/
        showContextmenu : function(e){
            var that = e.data.that,
                elem = e.data.elem,
                base = that.getData(elem),
                theme = base.options.theme,
                buttonMode = base.options.buttonMode;
            /**********************************************/
            if(base.options.start(base) === false){
                return false;
            }
            $(base.options.appendTo).find('div.'+base.themePrefix+theme).remove();
            base.$menu = that.createMenu(elem,base.options.menu,$(base.options.appendTo),true,base);
            if (base.$menu) {
                that.show(elem,e);
                base.$menu.on('mousedown',function(e){
                    e.preventDefault();
                    return false;
                });
                $(document).unbind('mousedown').one('mousedown',function(){
                    that.hide(elem,$(base.options.appendTo));
                });
                /*
                $('<div/>').css({position:'absolute',left:0,top:0,zIndex:1000,width:'100%',height:'100%'}).unbind('mousedown').one('mousedown',function(){
                    that.hide(elem,$(base.options.appendTo));
                    $(this).remove();
                }).appendTo('body');
                */
            }
            
        },
        /**
         *
         *
        **/
        show : function(elem,e){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
            var pos = this.getRootMenuPosition(elem,e);
            base.$menu.css( {top:pos.y, left:pos.x , position:"absolute",zIndex:9999} );
        },
        /**
         *
         *
        **/
        createMenu : function(elem , menu , $appendTo , isRootMenu , base){
            var that = this,
               // base = this.getData(elem),
                background_position = [],
                $div = $('<div/>'),
                GROUP = 0,
                drawCount = 0,
                isFirstMenu = true,
                visibleCount = 0,
                $ul = $('<ul/>').appendTo($div);
            /**********************************************/
            if(isRootMenu === true){
                $div.addClass(base.themePrefix+base.options.theme);
            }
            $div.addClass('sub-menu');

            $.each(menu,function(i,o){
                if(o.RBA_OP_ID && $.isFunction(base.options.RBA_OP_ID )){
                    base.options.RBA_OP_ID(o);
                }

                if( o.RBA_MODEL && $.isFunction(base.options.RBA_MODEL._GLOBAL) ){
                    base.options.RBA_MODEL._GLOBAL(o,base);
                }

                if( o.RBA_MODEL && $.isFunction(base.options.RBA_MODEL[o.RBA_MODEL]) ){
                    base.options.RBA_MODEL[o.RBA_MODEL](o,base);
                }

                if(o.VISIBLE !== false){
                    visibleCount++;
                }
            });
            $.each(menu,function(i,o){
                if(!o.CHILD)
                    o = $.extend(true,{},base.defaultMenu,o);
                if(GROUP != o.GROUP && isFirstMenu == false && visibleCount != drawCount){
                    $('<li/>').addClass(base.classSeparator).appendTo($ul).on('click',function(e){
                        e.preventDefault();
                        return false;
                    });
                }
                var $li = $('<li/>');
                if(o.TEXT){

                    var $text = '<span class="menu-text">'+o.TEXT+'</span>';

                    var $menuItem = $('<div/>').addClass(base.classMenuItem).html($text).appendTo($li);

                    if(o.CHILD){
                        var childVisibleCount = 0
                        $.each(o.CHILD , function(i,o){
                            if(o.VISIBLE !== false){
                                childVisibleCount ++;
                            }
                        });
                        if(childVisibleCount != 0 && o.DISABLED !== true){
                            $menuItem.addClass(base.classSubMenuIndicator);
                        }else{
                            $menuItem.addClass(base.classMenuDisabled);
                        }
                    }
                    if(o.BACKGROUND_POSITION){
                        if(o.DISABLED === true){
                            background_position = o.BACKGROUND_POSITION.GRAYOUT;
                        }else{
                            background_position = o.BACKGROUND_POSITION.DEFAULT;
                        }
                        background_position[0] = parseInt(background_position[0],10).toString()+'px';
                        background_position[1] = parseInt(background_position[1],10).toString()+'px';
                        var menuImage = $('<span/>').addClass('menu-image').css({'background-position':background_position.join(' ')}).appendTo($menuItem);
                        if(base.options.icons_src){
                            menuImage.css({'background-image':'url('+base.options.icons_src+')'});
                        }
                    }
                    if(o.BACKGROUND_IMG){
                        var menuImage = $('<span/>').addClass('menu-image').css({'background-position':'0px 0px','background-image':'url('+o.BACKGROUND_IMG+')'}).appendTo($menuItem);
                    }
                        $menuItem.find('span:eq(0)').appendTo($menuItem);
                    if(o.DISABLED === true){
                        $li.find('> div').addClass(base.classMenuDisabled);
                        if(o.CHILD){
                            $menuItem.addClass(base.classSubMenuIndicatorGray);
                        }
                    }else{
                        if($.isFunction(o.ONCLICK)){
                            $li.on('click',{o:o},function(e){
                                e.data.o.ONCLICK(e.data.o,base);
                                var $menuDiv = $(this).parents().find('div.'+base.themePrefix+base.options.theme);
                                var $menuItemLv1 = $menuDiv.find('> ul > li > div.menu-item');
                                var $subMenu = $menuDiv.find('li div.sub-menu');
                                if( $(this).siblings().find(' > div.sub-menu').length == 0){
                                    $menuItemLv1.removeClass(base.classMenuItemHover);
                                }
                                if(!e.data.o.CHILD && base.options.buttonMode === true){
                                    if( $(this).siblings().find(' > div.sub-menu').length == 0){
                                        $(this).find(' > div.menu-item').addClass(base.classMenuItemHover);
                                    }
                                    $subMenu.remove();
                                    e.preventDefault();
                                    return false;
                                }
                            });
                        }
                        $li.on('click',{o:o,buttonMode:base.options.buttonMode},function(e){
                            theme = base.options.theme;
                            if(e.data.buttonMode === true){
                                var $menuDiv = $(this).parents().find('div.'+base.themePrefix+theme);
                                var $menuItemLv1 = $menuDiv.find('> ul > li > div.menu-item');
                                var $subMenu = $menuDiv.find('li div.sub-menu');
                                if(o.CHILD){
                                    e.preventDefault();
                                    return false;
                                }
                                if(!$.isFunction(o.ONCLICK)){
                                    e.preventDefault();
                                    return false;
                                }
                                if($menuItemLv1.hasClass(base.classMenuItemHover) && $subMenu.length == 0){
                                    e.preventDefault();
                                    return false;
                                }
                                if($subMenu.length > 1){
                                    $subMenu.remove();
                                    $menuItemLv1.removeClass(base.classMenuItemHover);
                                    e.preventDefault();
                                    return false;
                                }
                            }else{
                                //prevent event when click the node
                                if(o.CHILD){
                                    e.preventDefault();
                                    return false;
                                }
                                if(!$.isFunction(o.ONCLICK)){
                                    e.preventDefault();
                                    return false;
                                }
                                var $menuDiv = $(this).parents().find('div.'+base.themePrefix+theme);
                                $menuDiv.remove();
                            }
                        });
                    }
                }
                if(o.DISABLED !== true){
                    $li.hover(function(e){
                        if(base.options.buttonMode === true && isRootMenu === true){
                            $(this).parent().siblings()
                                .find('div.sub-menu').remove();
                        }
                        $(this).find('> div.menu-item').addClass(base.classMenuItemHover);
                    },function(){
                        $(this).find('> div').removeClass(base.classMenuItemHover);
                        $(this).siblings().find('> div').removeClass(base.classMenuItemHover);
                    });
                    if(o.CHILD){
                        if(base.options.buttonMode !== true || isRootMenu != true){
                            $li.hover(function(e){
                                var $subDiv = that.createMenu(elem,o.CHILD,$(this),false,base),
                                    pos = that.getSubMenuPosition(elem,e,$(this));
                                if(base.options.buttonMode === false){
                                    $subDiv.css({left:pos.x,top:pos.y});
                                }else{
                                    if(isRootMenu !== true)
                                        $subDiv.css({left:pos.x,top:pos.y});
                                }
                                if(document.documentMode <= 7 ){
                                    var $o_submenu =$(this).find('> .sub-menu')
                                    var subMenuWidth = $o_submenu.outerWidth();
                                    $o_submenu.find('li .menu-item').width(subMenuWidth-26);
                                    var subMenuLiWidth = $o_submenu.find('li').width()
                                    $o_submenu.find('li.dot-line-separator').width(subMenuLiWidth);
                                }
                            },function(e){
                                var $submenu = $(this).find('div.sub-menu');
                                setTimeout(function(){
                                    $submenu.remove();
                                },base.options.hoverTimeout);
                            });
                        }
                        if(base.options.buttonMode === true && isRootMenu === true){
                            $li.on('click',{buttonMode:base.options.buttonMode},function(e){
                                var buttonMode = e.data.buttonMode;
                                var $menuDiv = $(this).parents().find('div.'+base.themePrefix+theme);
                                var $subMenu = $menuDiv.find('li div.sub-menu');
                                if($subMenu.length == 0 || $menuDiv.find('> ul > li > div.menu-item').hasClass(base.classMenuItemHover)){
                                    if($menuDiv.find('> ul > li > div.menu-item').hasClass(base.classMenuItemHover)){
                                        $subMenu.remove();
                                    }
                                    var $subDiv = that.createMenu(elem,o.CHILD,$(this),false,base),
                                        pos = that.getSubMenuPosition(elem,e,$(this));
                                    if(document.documentMode <= 7 ){
                                        var $o_submenu =$(this).find('> .sub-menu')
                                        var subMenuWidth = $o_submenu.outerWidth();
                                        $o_submenu.find('li .menu-item').width(subMenuWidth-26);
                                        var subMenuLiWidth = $o_submenu.find('li').width()
                                        $o_submenu.find('li.dot-line-separator').width(subMenuLiWidth);
                                    }
                                    if(buttonMode === false){
                                        $subDiv.css({left:pos.x,top:pos.y});
                                    }else{
                                        if(isRootMenu !== true)
                                            $subDiv.css({left:pos.x,top:pos.y});
                                    }
                                    $(this).parent().find('div.sub-menu').mouseleave(function(){
                                        var $this = $(this);
                                        setTimeout(function(){
                                            $this.filter(function(){
                                                return ( $this.parent().find('> div.menu-item').hasClass(base.classMenuItemHover) ) ? false : true;
                                            }).remove();
                                        },base.options.buttonModeHoverTimeout);
                                    });
                                }else{
                                    $menuDiv.find('> ul > li > div.menu-item').removeClass(base.classMenuItemHover);
                                    $subMenu.remove();
                                }
                            });
                        }
                    }
                }
                GROUP = o.GROUP;
                if(o.VISIBLE !== false){
                    isFirstMenu = false;
                    drawCount++;
                    $li.appendTo($ul);
                }

                if(base.options.separator && isRootMenu && i < menu.length-1 && base.options.buttonMode === true){
                    var $liSeparator = $('<li/>').appendTo($ul);
                    var $divSeparator= $('<div/>').addClass('v-separator');

                    var $text = '<span class="menu-text">&nbsp;</span>';

                    $divSeparator.html( $text ).appendTo($liSeparator)

                }
            });
            $appendTo.append($div);
            //remove siblins dotted line separator if repeated
            $.each( $('> ul > li.'+base.classSeparator ,$div)  , function(i,o){
                $(o).next().filter(function(){
                    if($(this).hasClass(base.classSeparator)){
                        return true;
                    }else{
                        return false;
                    }
                }).remove();
            });
            //remove the last v-separator
            if(isRootMenu && base.options.buttonMode === true){
                $('> ul > li:last' ,$div).filter(function(){
                    return $(this).find('> div').hasClass('v-separator');
                }).remove();
            }
            $div
                //.disableSelection()
                .bind('contextmenu',function(e){
                    e.preventDefault();
                });
            return $div;
        },
        /**
         *
         *
        **/
        disableSelection : function(elem , target ){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
            $.each(target,function(i,o) {
                $(o)
                    .attr('unselectable', 'on')
                    .css({
                        '-moz-user-select':'none',
                        '-o-user-select':'none',
                        '-khtml-user-select':'none',
                        '-webkit-user-select':'none',
                        '-ms-user-select':'none',
                        'user-select':'none'
                    })
                    .attr('unselectable','on')
                    .on('selectstart',function(){
                        return false;
                    });
            });
        },
        /**
         *
         *
        **/
        getRootMenuPosition : function(elem ,e){
            var that = this,
                base = that.getData(elem),
                $target = base.$menu;
            /**********************************************/
            var x = e.pageX,
                y = e.pageY,
                $w = $(window),
                w = $target.width(),
                h = $target.height(),
                ww = $w.width(),
                hh = $w.height(),
                maxRight = x+w-$w.scrollLeft(),
                maxBottom = y+h-$w.scrollTop();
            if (maxRight > ww) {
                x -= (maxRight-ww+5);
            }
            if (maxBottom > hh) {
                y -= (maxBottom-hh+5);
            }
            return {x:x,y:y};
        },
        getSubMenuPosition : function(elem,e,$target){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
            var $subMenu = $target.find('div.sub-menu'),
                $menuItem = $subMenu.find('div.menu-item'),
                paddingTopW = parseInt($menuItem.css('paddingTop'),10),
                borderTopW = parseInt($menuItem.css('border-top-width'),10),
                x = $target.offset().left,
                ajdHeight = paddingTopW+borderTopW
                y = $target.offset().top,
                y_rel = $target.position().top-ajdHeight,
                itemW = $subMenu.outerWidth(),
                itemH = $subMenu.outerHeight(),
                w = $target.width(),
                h = $target.height(),
                $w = $(window),
                ww = $w.width(),
                hh = $w.height(),
                maxRight = x+w+itemW-$w.scrollLeft(),
                maxBottom = y+h+itemH-$w.scrollTop();
                if (maxRight > ww) {
                    w = -itemW;
                }
                if (maxBottom - hh > 10) {
                    y = y_rel-(maxBottom-hh)+h-10;
                }else{
                    y = $target.position().top-paddingTopW+borderTopW;
                }
                var diff = parseInt( $target.find('> div.menu-item').css('paddingTop') , 10);
            return {x:w,y:y};
        },
        /**
         *
         *
        **/
        hide : function(elem,$appendTo){
            var that = this,
                base = that.getData(elem),
                theme = base.options.theme,
                buttonMode = base.options.buttonMode;
            /**********************************************/
            if(buttonMode === false){
                $appendTo.find('div.'+base.themePrefix+theme).remove();
            }else{
                $appendTo.find('div.'+base.themePrefix+theme).find('> ul > li > div.sub-menu').remove();
            }
            $('div.'+base.options.classUIcontextmenu).removeClass(base.options.classUIcontextmenu);
        },
        /**
         *
         *
        **/
        displayContextmenuByDefault : function(elem){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
            base.$elem.empty();
            that.createMenu(elem,base.options.menu,base.$elem,true,base);
        },
        /**
         *
         *
        **/
        ToDoDefaultOptionsOrPlugin : function(elem){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
        },
        /**
         *
         *
        **/
        reload : function(elem,options){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
            base.options = $.extend(true,{},base.options,options);
            this.displayContextmenuByDefault(elem);
        },
        /**
         *
         *
        **/
        ToDoDefaultOptionsOrPlugin : function(elem){
            var that = this,
                base = that.getData(elem);
            /**********************************************/
        }
    };
    $.fn[PLUGIN_NAME].publicMethods = {
        /**
         *
         *
        **/
        reload : function(elem,args){
            $.fn[PLUGIN_NAME].internalMethods.reload(elem , args[0]);
        },
        /**
         *
         *
        **/
        ToDoDefaultOptionsOrPlugin : function(elem,args){
            $.fn[PLUGIN_NAME].internalMethods.ToDoDefaultOptionsOrPlugin(elem , args[0] , args[1] );
        }
    };
    $.fn[PLUGIN_NAME].defaults = $.extend({}, {
        buttonMode : false,
        appendTo:'body',
        theme : 'osce',
        hoverTimeout : 120,
        buttonModeHoverTimeout : 500,
        classUIcontextmenu : 'ui-contextmenu',
        icons_src: false,
        RBA_MODEL : {
            _GLOBAL : function(o,base){
            }
        },
        start : function(base){
            return true;
        },
        separator : true,
        exclude : []
    });
    $.fn[PLUGIN_NAME].base = $.extend({}, {
        themePrefix : 'context-menu-theme-',
        classMenuItem : 'menu-item',
        classMenuItemHover : 'menu-item-hover',
        classSeparator : 'dot-line-separator',
        classSubMenuIndicator : 'sub-menu-indicator',
        classSubMenuIndicatorGray : 'sub-menu-indicator-gray',
        classImgDefault : 'menu-default',
        classMenuDisabled : 'menu-item-disabled',
        defaultMenu : {
            ONCLICK : function(){
            }
        }
    });
})(jQuery);